package vip.liux.backend.infrastructure.message;

import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.sql.init.OnDatabaseInitializationCondition;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.sql.init.dependency.DatabaseInitializationDependencyConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

import javax.sql.DataSource;

@AutoConfiguration
@ConditionalOnBean(DataSource.class)
@Import({DatabaseInitializationDependencyConfigurer.class})
public class MessageAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public MessageRecordRepository messageRecordRepository(
            DataSource dataSource,
            @MessageDataSource ObjectProvider<DataSource> messageDataSource) {
        JdbcMessageRecordRepositoryImpl repository = new JdbcMessageRecordRepositoryImpl();
        repository.setDataSource(messageDataSource.getIfAvailable(() -> dataSource));
        return repository;
    }

    @Configuration(proxyBeanMethods = false)
    @EnableConfigurationProperties(MessageProperties.class)
    @Conditional(OnMessageDatasourceInitializationCondition.class)
    static class DataSourceInitializerConfiguration {

        @Bean
        @ConditionalOnMissingBean(MessageDataSourceScriptDatabaseInitializer.class)
        MessageDataSourceScriptDatabaseInitializer messageDataSourceInitializer(
                DataSource dataSource,
                @MessageDataSource ObjectProvider<DataSource> messageDataSource,
                MessageProperties properties) {
            return new MessageDataSourceScriptDatabaseInitializer(messageDataSource.getIfAvailable(() -> dataSource),
                    properties);
        }
    }

    static class OnMessageDatasourceInitializationCondition extends OnDatabaseInitializationCondition {
        OnMessageDatasourceInitializationCondition() {
            super("Jdbc Message", "spring.message.jdbc.initialize-schema");
        }
    }
}
